/*-
 * Copyright (c) 2013 Shang-Rong Cai. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $ NUMTK: numtk.h    Rev. 0.0.1    2013-11-05T15:53+08:00 $
 */

#include <stddef.h>
#include <bscdef.h>

#ifndef NUMTK_H
#define NUMTK_H

/* Stripe Pointer Type */
typedef struct
{
    sidx_t head;
    sidx_t tail;
} sidxpair_t;


/* Ordering Type: None (0), Row-wise (1), Column-wise(2) */
#define RDR_NONE 0
#define ROW_WISE 1
#define COL_WISE 2


/* Dual Indexed Single-Precision Floating-Point Data Type */
typedef struct
{
    sidx_t r_idx;
    sidx_t c_idx;
    float value;
} diflt_t;


/* Dual Indexed Single-Precision Floating-Point Data Block Type */
typedef struct
{
    size_t r_sz;  /* 1st index, usually as row size */
    size_t c_sz;  /* 2nd index, usually as column size */
    size_t e_sz;  /* Number of entries */
    size_t k_sz;  /* Exact block size */

    diflt_t *item;  /* Data items */
} difk_t;


int difk_init(size_t rz, size_t cz, size_t kz, difk_t *bk);

int difk_dest(difk_t *bk);

void difk_stdout(difk_t *bk);


/* Coupled Index Single-Precision Floating-Point Data Type */
typedef struct
{
    sidx_t index;
    float value;
} ciflt_t;


/* Compressed Coupled Index Single-Precision Floating-Point Data Block Type */
typedef struct
{
    size_t r_sz;  /* 1st index, usually as row size */
    size_t c_sz;  /* 2nd index, usually as column size */
    size_t e_sz;  /* Number of entries */
    size_t k_sz;  /* Exact block size */

    uint8_t flag;  /* Ordering flag: row-wise or column-wise */

    sidxpair_t *sptr;  /* Stripe pointer */
    ciflt_t *item;  /* Data items */
} cifk_t;

int cifk_init(size_t rz, size_t cz, size_t kz, uint8_t flg, cifk_t *bk);

int cifk_dest(cifk_t *bk);

int cifk_stdout(cifk_t *bk);


/* Dual Indexed Double-Precision Floating-Point Data Type */
typedef struct
{
    sidx_t r_idx;
    sidx_t c_idx;
    double value;
} didbl_t;


/* Dual Indexed Double-Precision Floating-Point Data Block Type */
typedef struct
{
    size_t r_sz;  /* 1st index, usually as row size */
    size_t c_sz;  /* 2nd index, usually as column size */
    size_t e_sz;  /* Number of entries */
    size_t k_sz;  /* Exact block size */

    didbl_t *item;  /* Data items */
} didk_t;

int didk_init(size_t rz, size_t cz, size_t kz, didk_t *bk);

int didk_dest(didk_t *bk);

void didk_stdout(didk_t *bk);


/* Coupled Index Double-Precision Floating-Point Data Type */
typedef struct
{
    sidx_t index;
    double value;
} cidbl_t;


/* Compressed Coupled Index Double-Precision Floating-Point Data Block Type */
typedef struct
{
    size_t r_sz;  /* 1st index, usually as row size */
    size_t c_sz;  /* 2nd index, usually as column size */
    size_t e_sz;  /* Number of entries */
    size_t k_sz;  /* Exact block size */

    uint8_t flag;  /* Ordering flag: row-wise or column-wise */

    sidxpair_t *sptr;  /* Stripe pointer */
    cidbl_t *item;  /* Data items */
} cidk_t;

int cidk_init(size_t rz, size_t cz, size_t kz, uint8_t flg, cidk_t *bk);

int cidk_dest(cidk_t *bk);

int cidk_stdout(cidk_t *bk);


/* Row Major Direct Single-Precision Floating-Point Block */
typedef struct
{
    size_t rz;  /* Row size*/
    size_t cz;  /* Column size */
    size_t kz;  /* Exact block size */

    float *eval;  /* Values */
} rdff_t;


/* Row Major Direct Double-Precision Floating-Point Block */
typedef struct
{
    size_t rz;  /* Row size*/
    size_t cz;  /* Column size */
    size_t kz;  /* Exact block size */

    double *eval;  /* Values */
} rdfd_t;


extern int rdfd_init(size_t rz, size_t cz, rdfd_t *rdfd);

extern int rdfd_dest(rdfd_t *rdfd);

extern int rdfd_stdout(rdfd_t *rdfd);


/* Row Major Specific Double-Precision Floating-Point Block */
typedef struct
{
    size_t rz;  /* Row size */
    size_t cz;  /* Column size */
    size_t kz;  /* Exact block size */

    uidx_t *rptr;  /* Row pointers */
    fltd_t *elst;  /* Entries */
} rsfd_t;


extern int rsfd_init(size_t rz, size_t cz, size_t kz, rsfd_t *rsfd);

extern int rsfd_dest(rsfd_t *rsfd);


extern int rsfd_stdout(rsfd_t *rsfd);

#endif
